package com.hundsun.cprs.yyt.gateway.service.trade.impl;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.hundsun.cprs.yyt.gateway.vo.*;
import com.hundsun.cprs.yyt.service.account.service.AccountStatService;
import com.hundsun.cprs.yyt.service.common.service.RemoteTradeFundService;
import com.hundsun.cprs.yyt.service.dilivery.domain.Delivery;
import com.hundsun.cprs.yyt.service.dilivery.service.DeliveryService;
import com.hundsun.cprs.yyt.service.system.dto.TradingTimePeriodReponse;
import com.hundsun.cprs.yyt.service.system.service.TradingTimePeriodService;
import com.hundsun.cprs.yyt.service.trade.domain.TradeEntrust;
import com.hundsun.cprs.yyt.service.trade.domain.TradeMatchDetail;
import com.hundsun.cprs.yyt.service.trade.enums.EnumEntustBSType;
import com.hundsun.cprs.yyt.service.trade.service.TradeEntrustService;
import com.hundsun.cprs.yyt.service.trade.service.TradeMatchDetailService;
import com.hundsun.cprs.yyt.service.trade.service.TradeMatchService;
import com.hundsun.cprs.yyt.util.StringUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.Validate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.hundsun.cprs.yyt.common.enums.EnumBusinessCode;
import com.hundsun.cprs.yyt.common.enums.EnumCommonCode;
import com.hundsun.cprs.yyt.common.exception.ServiceCodeException;
import com.hundsun.cprs.yyt.gateway.request.OrderQueryRequest;
import com.hundsun.cprs.yyt.gateway.request.PlaceOrderRequest;
import com.hundsun.cprs.yyt.gateway.response.BaseResponse;
import com.hundsun.cprs.yyt.gateway.response.OrderListResponse;
import com.hundsun.cprs.yyt.gateway.response.OrderResponse;
import com.hundsun.cprs.yyt.gateway.response.PlaceOrderResponse;
import com.hundsun.cprs.yyt.gateway.service.BaseService;
import com.hundsun.cprs.yyt.gateway.service.trade.OrderCommonService;
import com.hundsun.cprs.yyt.service.common.dto.UserAccountDTO;
import com.hundsun.cprs.yyt.service.common.service.RemoteUserService;
import com.hundsun.cprs.yyt.service.dilivery.domain.DiliveryAddress;
import com.hundsun.cprs.yyt.service.dilivery.service.DiliveryAddressService;
import com.hundsun.cprs.yyt.service.goods.domain.GoodsSpecs;
import com.hundsun.cprs.yyt.service.goods.dto.GoodsInfo;
import com.hundsun.cprs.yyt.service.goods.enums.EnumGoodsStatus;
import com.hundsun.cprs.yyt.service.goods.service.GoodsService;
import com.hundsun.cprs.yyt.service.goods.service.GoodsSkuService;
import com.hundsun.cprs.yyt.service.order.domain.query.OrderInfoQuery;
import com.hundsun.cprs.yyt.service.order.dto.DeliveryMethod;
import com.hundsun.cprs.yyt.service.order.dto.GoodsItem;
import com.hundsun.cprs.yyt.service.order.dto.OrderInfo;
import com.hundsun.cprs.yyt.service.order.enums.EnumDeliveryMethod;
import com.hundsun.cprs.yyt.service.order.enums.EnumsOrderStatus;
import com.hundsun.cprs.yyt.service.order.service.OrderService;
import com.hundsun.cprs.yyt.service.system.enums.EnumBussinessParam;
import com.hundsun.cprs.yyt.service.system.service.BusinessParamHelper;
import com.hundsun.cprs.yyt.service.system.service.BussinessParamService;
import com.hundsun.cprs.yyt.util.BeanUtils;
import com.hundsun.cprs.yyt.util.DateUtil;

@Service
public class OrderCommonServiceImpl extends BaseService implements OrderCommonService {

    @Value("${newPlateCode}")
    private String newPlateCode;
    @Value("${is.validate.pay.password:false}")
    private String isValidatePayPassword;//是否校验支付密码

    @Autowired
    private OrderService orderService;
    
    @Autowired
    private GoodsSkuService skuService;
    
    @Autowired
    private DiliveryAddressService diliveryAddressSerivce;
    
    @Autowired
    private GoodsService goodsService;
    
    @Autowired
    private RemoteUserService userService;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private TradingTimePeriodService tradingTimePeriodService;

    @Autowired
    private AccountStatService accountStatService;

    @Autowired
    private TradeEntrustService tradeEntrustService;

    @Autowired
    private RemoteTradeFundService remoteTradeFundService;
    
    @Override
    public PlaceOrderResponse placingOrderAndPay(PlaceOrderRequest request) {
        PlaceOrderResponse response = new PlaceOrderResponse();
        try {
            Validate.notNull(request, "参数非法");
            Validate.notNull(request.getUserId(),"会员信息必填");
            Validate.notNull(request.getSkuId(),"商品SKU必填");
            Validate.notNull(request.getQuantity(),"商品数量必填");
            Validate.isTrue(request.getQuantity() > 0,"商品数量必须大于0");
            Validate.notNull(request.getDeliveryType(),"配送方式必填");
            if (StringUtil.equals(isValidatePayPassword,"true")){
                Validate.notNull(request.getPayPassword(),"支付密码必填");
            }
            if (request.getDeliveryType() == EnumDeliveryMethod.SELFGET.ordinal()){
                Validate.notNull(request.getSelfGetPhone(),"自提人手机号必填");
                Validate.notNull(request.getSelfGetTime(),"自提时间必填");
                Validate.notNull(request.getSeleGetName(),"自提人姓名必填");
            }

            //日终清算期间不允许交易控制
            clearingTradeControl();

            //交易时间段控制
            tradingTimePeriodControl();

            //新人专场控制
            newPlateControl(request);
            
            GoodsSpecs sku = skuService.selectByPrimaryKey(request.getSkuId());
            if (sku == null) {
                throw new IllegalArgumentException("商品SKU不存在");
            }
            
            UserAccountDTO user = userService.getUserDetailByUserId(request.getUserId());
            if (user == null) {
                throw new IllegalArgumentException("会员信息不存在");
            }
            if (!user.isRealName()) {
                throw new ServiceCodeException(EnumBusinessCode.BUSINESS_1002.getErrorNo(),"会员未实名");
            }
            //校验支付密码是否正确
            if (StringUtil.equals(isValidatePayPassword,"true") && !remoteUserService.checkPassword(request.getUserId(),request.getPayPassword())){
                throw new ServiceCodeException(EnumBusinessCode.BUSINESS_1028.getErrorNo(),EnumBusinessCode.BUSINESS_1028.getErrorInfo());
            }
            DiliveryAddress receiver = null;
            if (request.getDiliveryId() != null) {
                receiver = diliveryAddressSerivce.selectAddressDetailByAddressId(request.getDiliveryId());
                if (receiver == null) {
                    throw new IllegalArgumentException("会员地址不存在");
                }
                //过滤掉自提地址userId为0的情况
                if (receiver.getUserId().compareTo(0L) != 0 && Long.compare(receiver.getUserId(),request.getUserId()) != 0) {
                    throw new IllegalArgumentException("会员地址信息不一致");
                }
            }
            
            GoodsInfo goodsInfo = goodsService.selectGoodsInfoByIdFromCache(sku.getGoodsId(), sku.getAreaCode());
            if (goodsInfo == null || EnumGoodsStatus.CANCEL_PUBLISH.getCode().equals(goodsInfo.getStatus())) {
                throw new IllegalArgumentException("商品已下架");
            }
            
            GoodsItem item = new GoodsItem();
            item.setSku(sku);
            item.setQuantity(request.getQuantity());
            item.setGoods(goodsInfo);
            
            DeliveryMethod deliveryMethod = new DeliveryMethod();
            deliveryMethod.setDiliveryType(request.getDeliveryType());
            deliveryMethod.setSelfGetTime(request.getSelfGetTime());
            deliveryMethod.setSelfGetPhone(request.getSelfGetPhone());
            deliveryMethod.setSeleGetName(request.getSeleGetName());
            deliveryMethod.setReciver(receiver);
            
            //下单支付
            OrderInfo order = orderService.createOrder(user,item,deliveryMethod,request.getMemo());
            response.setOrderId(order.getId());
            response.setSn(order.getSn());
        } catch (IllegalArgumentException e) {
            response.setErrorNo(EnumBusinessCode.BUSINESS_1000.getErrorNo());
            response.setErrorInfo(e.getMessage());
        } catch (ServiceCodeException e) {
            response.setErrorNo(e.getErrorCode());
            response.setErrorInfo(e.getErrorDesc());
        } catch (Exception e) {
            logger.error("处理异常", e);
            response.setErrorNo(EnumCommonCode.COMMON_SERVER_ERROR.getErrorNo());
            response.setErrorInfo(EnumCommonCode.COMMON_SERVER_ERROR.getErrorInfo());
        }
        return response;
    }

    @Override
    public OrderListResponse selectOrderList(OrderQueryRequest request) {
        OrderListResponse response = new OrderListResponse();
        try{
            Validate.notNull(request, "参数非法");
            Validate.notNull(request.getUserId(),"会员信息必填");
            
            OrderInfoQuery query = BeanUtils.transfrom(OrderInfoQuery.class, request);
            orderService.selectOrderInfoByPage(query);
            
            if (query.getTotalCount() > 0) {
                response.setTotalCount(query.getTotalCount());
                response.setResult(BeanUtils.batchTransform(OrderVo.class, query.getData()));
            }
        } catch (IllegalArgumentException e) {
            response.setErrorNo(EnumBusinessCode.BUSINESS_1000.getErrorNo());
            response.setErrorInfo(e.getMessage());
        } catch (ServiceCodeException e) {
            response.setErrorNo(e.getErrorCode());
            response.setErrorInfo(e.getErrorDesc());
        } catch (Exception e) {
            logger.error("处理异常", e);
            response.setErrorNo(EnumCommonCode.COMMON_SERVER_ERROR.getErrorNo());
            response.setErrorInfo(EnumCommonCode.COMMON_SERVER_ERROR.getErrorInfo());
        }
        return response;
    }

    @Override
    public OrderResponse getOrderDetail(Long userId,Long orderId) {
        OrderResponse response = new OrderResponse();
        try{
            Validate.notNull(orderId, "订单信息必填");
            Validate.notNull(userId, "用户信息必填");
            OrderInfo orderInfo = orderService.selectOrderInfoById(orderId);
            if (orderInfo.getUserId().compareTo(userId) != 0){
                throw new ServiceCodeException(EnumBusinessCode.BUSINESS_1522.getErrorNo(),EnumBusinessCode.BUSINESS_1522.getErrorInfo());
            }
            if (orderInfo != null){
                OrderVo orderVo = BeanUtils.transfrom(OrderVo.class,orderInfo);
                orderVo.setOrderItems(BeanUtils.batchTransform(OrderItemVo.class,orderInfo.getOrderItems()));
                fillDeliveryInfo(orderVo,orderInfo);//填充物流信息
                fillTradeMatchDetailInfo(orderVo,orderInfo);//匹配交易对手方信息
                response.setResult(orderVo);
            }
        } catch (IllegalArgumentException e) {
            response.setErrorNo(EnumBusinessCode.BUSINESS_1000.getErrorNo());
            response.setErrorInfo(e.getMessage());
        } catch (ServiceCodeException e) {
            response.setErrorNo(e.getErrorCode());
            response.setErrorInfo(e.getErrorDesc());
        } catch (Exception e) {
            logger.error("处理异常", e);
            response.setErrorNo(EnumCommonCode.COMMON_SERVER_ERROR.getErrorNo());
            response.setErrorInfo(EnumCommonCode.COMMON_SERVER_ERROR.getErrorInfo());
        }
        return response;
    }

    @Override
    public BaseResponse confirmOrder(Long userId, Long orderId) {
        BaseResponse response = new BaseResponse();
        try{
            Validate.notNull(orderId, "订单编号必填");
            Validate.notNull(orderId, "用户id必填");
            OrderInfo orderInfo = orderService.selectOrderInfoById(orderId);
            if (orderInfo == null){
                throw new ServiceCodeException(EnumBusinessCode.BUSINESS_1501.getErrorNo(),EnumBusinessCode.BUSINESS_1501.getErrorInfo());
            }
            if (Long.compare(userId,orderInfo.getUserId()) != 0){
                throw new ServiceCodeException(EnumBusinessCode.BUSINESS_1504.getErrorNo(),EnumBusinessCode.BUSINESS_1504.getErrorInfo());
            }
            //校验订单状态是否为待收货
            if (!orderInfo.getStatus().equals(EnumsOrderStatus.DELIVERED.getStatus())){
                throw new ServiceCodeException(EnumBusinessCode.BUSINESS_1502.getErrorNo(),EnumBusinessCode.BUSINESS_1502.getErrorInfo());
            }
            //设置订单状态为已完成
            orderInfo.setStatus(EnumsOrderStatus.COMPELETED.getStatus());
            orderInfo.setCompleteDate(new Date());
            orderService.updateOrderStatus(orderInfo);
        } catch (IllegalArgumentException e) {
            response.setErrorNo(EnumBusinessCode.BUSINESS_1000.getErrorNo());
            response.setErrorInfo(e.getMessage());
        } catch (ServiceCodeException e) {
            response.setErrorNo(e.getErrorCode());
            response.setErrorInfo(e.getErrorDesc());
        } catch (Exception e) {
            logger.error("处理异常", e);
            response.setErrorNo(EnumCommonCode.COMMON_SERVER_ERROR.getErrorNo());
            response.setErrorInfo(EnumCommonCode.COMMON_SERVER_ERROR.getErrorInfo());
        }
        return response;
    }

    public void clearingTradeControl(){
        if (!remoteTradeFundService.isTradeAble()){
            throw new ServiceCodeException(EnumBusinessCode.BUSINESS_1036.getErrorNo(),EnumBusinessCode.BUSINESS_1036.getErrorInfo());
        }
    }

    public void tradingTimePeriodControl(){
        try{
            //当前时间不在两个时间段内，则不允许交易
            TradingTimePeriodReponse response = tradingTimePeriodService.isTradingTimePeriod();
            if (!response.getFlag()){
                String errorInfo = MessageFormat.format(EnumBusinessCode.BUSINESS_1123.getErrorInfo(),response.getTimePeriod());
                throw new ServiceCodeException(EnumBusinessCode.BUSINESS_1123.getErrorNo(),errorInfo);
            }
        }catch (ServiceCodeException e){
            throw e;
        }catch (Exception e){
            logger.error("系统交易时间段格式有误，默认为24小时交易" + e);
        }
    }

    public void newPlateControl(PlaceOrderRequest request){
        //先获取sku信息，如果是新人专场的sku，则应用新人专场规则限制
        GoodsSpecs sku = skuService.selectByPrimaryKey(request.getSkuId());
        if (sku != null && sku.getPlateCode().equals(newPlateCode)){
            //判断下单人是否为新人，不是新人则打回
            if (!accountStatService.isNewUser(request.getUserId())){
                throw new ServiceCodeException(EnumBusinessCode.BUSINESS_1124.getErrorNo(),EnumBusinessCode.BUSINESS_1124.getErrorInfo());
            }
        }
    }

    public void fillDeliveryInfo(OrderVo orderVo,OrderInfo orderInfo){
        if (orderInfo.getDelivery() != null){
            orderVo.setDeliveryVo(BeanUtils.transfrom(DeliveryVo.class,orderInfo.getDelivery()));
        }
        if (orderInfo.getDiliveryAddress() != null){
            orderVo.setDiliveryAddressVo(BeanUtils.transfrom(DiliveryAddressVo.class,orderInfo.getDiliveryAddress()));
        }
    }

    public void fillTradeMatchDetailInfo(OrderVo orderVo,OrderInfo orderInfo){
        if (CollectionUtils.isNotEmpty(orderInfo.getTradeMatchDetailList())){
                List<TradeMatchDetailVo> tradeMatchDetailVoList = new ArrayList<>();
                for (TradeMatchDetail tradeMatchDetail:orderInfo.getTradeMatchDetailList()){
                    TradeMatchDetailVo tradeMatchDetailVo = new TradeMatchDetailVo();
                    TradeEntrust entrust = tradeEntrustService.getTradeEntrustById(tradeMatchDetail.getEntrust().getId());
                    tradeMatchDetailVo.setEntrustNo(entrust.getEntrustNo());
                    tradeMatchDetailVo.setFundAccount(tradeMatchDetail.getEntrust().getFundAccount());
                    tradeMatchDetailVo.setMatchAmount(tradeMatchDetail.getMatchAmount());
                    tradeMatchDetailVo.setMatchFundAmount(tradeMatchDetail.getMatchFundAmount());
                    tradeMatchDetailVo.setUserName(entrust.getUserName());
                    tradeMatchDetailVoList.add(tradeMatchDetailVo);
                }
                orderVo.setTradeMatchDetailVoList(tradeMatchDetailVoList);
            }
        }
}
